/*===== code build by mstore0.1.3 =====*/

/*===== mstoreDev/common#base:0 =====*/

function $$(namespace, factory, module){
    
    if(typeof namespace == 'function'){ //定义块执行
        var wrapper = function(fn){
            if(typeof fn != 'function'){
                return function(){};
            }
            return fn;
        };
        var $it = {
            click: function(fns){
                this.listen('click', fns);
            },
            listen: function(type, events){
                $.each(events, function(key, event){
                    $(document).on(type, '[jhand="'+ key +'"]', wrapper(event));
                });
            },
            extend: function(methods){
                $.each(methods, function(key, method){
                    if(!$it[key]){
                        $it[key] = wrapper(method);
                    }
                });
            },
            ajax: function(ajaxs){
                var $ajax = $it.ajax;
                $.each(ajaxs, function(key, ajax){
                    $ajax[key] = wrapper(ajax);
                });
            },
            tpl: function(tpls){
                var $tpl = $it.tpl;
                $.each(tpls, function(key, tpl){
                    $tpl[key] = wrapper(tpl);
                });
            },
            wait: function(fn){
                var asyncQueueFns;
                if(arguments.length > 1){ //多个并行流程
                    asyncQueueFns = [].slice.call(arguments); 
                }else if(typeof fn == 'function'){
                    asyncQueueFns = [fn];
                }else{
                    asyncQueueFns = fn.slice();
                }
                queue.push(asyncQueueFns);
                startQueueItem();
                return $it;
            },
            then: function(fn){
                queue.push(fn);
                startQueueItem();
                return $it;
            },
            error: function(callback){
                rejectCallback = callback;
            }
        };
        
        var queueTimer;
        var rejectCallback;
        var rejectObject;
        var queue = [];
        var nextQueueItem = function(){
            
            if(rejectObject){
                return rejectCallback && rejectCallback(rejectObject.info);
            }
            
            var queueItem = queue.shift();
            if(typeof queueItem == 'function'){
                queueItem();
                nextQueueItem();
            }else if(queueItem){
                var waitLength = queueItem.length;
                for(var i = 0; i < waitLength; i++){
                    queueItem[i](resolve, reject);
                }
            }
            
            function resolve(){
                if(--waitLength == 0){ //全部已触发
                    nextQueueItem();
                }
            }
            
            function reject(info){
                rejectObject = {
                    info: info
                };
            }
            
        };
        var startQueueItem = function(){
            clearTimeout(queueTimer);
            queueTimer = setTimeout(nextQueueItem);
        };
        namespace($it);
        $it.init && $it.init();
        $it.domready && $($it.domready);
        return;
    }
    
    module = module || $$;
    
    //定义新模块
    var prevmodule; //上一级模块
    var nextkey; //下一级模块的key
    namespace.replace(/[^.]+/g, function(key){
        prevmodule = module;
        nextkey = key;
        module = module[key] = module[key] || {};
    });
    
    var exports = typeof factory == 'function' ? factory() : factory;
    
    if(typeof exports == 'function' || {}.toString.call(exports) == '[object Array]'){ //传入的是函数或数组时，直接覆盖旧的模块
        prevmodule[nextkey] = exports;
    }else if({}.toString.call(exports) == '[object Object]'){ //传入的是对象，对旧模块进行遍历扩充
        for(var key in exports){
            module[key] = exports[key];
        }
    }
    
}

$$('info', function(){
    return function(data){
        if(window.console && window.console.info){
            if(console.info.apply){ //ie8下console.info.apply方法不存在
                console.info.apply(null, arguments);
            }else{
                console.info(data);
            }
        }
    };
});

/*===== mstoreDev/common#util:0 =====*/

var $util = function(){
    return {
        each: function each(data, callback){
            if(Array.isArray(data)){
                for(var i = 0; i < data.length; i++){
                    if(callback(data[i], i, data) === false){
                        break;
                    }
                }
            }else if({}.toString.call(data) == '[object Object]'){
                for(var i in data){
                    if(callback(data[i], i, data) === false){
                        break;
                    }
                }
            }
        },
        mix: function mix(target, source){
            for(var key in source){
                target[key] = source[key];
            }
            return target;
        },
        paramStringify: function(data){
            var paramArr = [];
            $.each(data, function(key, value){
                paramArr.push(key +'='+ encodeURIComponent(value));
            });
            return paramArr.join('&');
        },
        ajax: function (callback, data){
            $.ajax({
                url: '/',
                type: 'post',
                data: this.paramStringify(data || []),
                dataType: 'json',
                timeout: 60000,
                success: function(resp){
                    callback(resp);
                },
                error: function(data){
                    setTimeout(function(){
                        callback({
                            err: 'ZSTORE接口请求异常'
                        });
                    }, 666);
                }
            });
        }
    };
}();

/*===== mstoreDev/common#rtpl:0 =====*/

var $rtpl = (function(){
    
var utils = {
    $escape: escape,
    $tostring: tostring,
    $each: foreach
};

return rtpl;

function rtpl(str, data){
    
    //从函数注释内提取模板
    if(typeof str == 'function'){
        str = (str +'').match(/\/\*([\w\W]+)\*\//)[1];
    }
    
    data = data || {};

    var lines = [];
    
    foreach(
        str
            .replace(/\{\{\{/g, '{{')
            .replace(/\}\}\}/g, '}}')
            .replace(/\r/g, '')
            .split(/\n/g),
        function(line){
            if(/^\s*\{\{.+?\}\}\s*$/.test(line)){
                lines.push(trim(line));
            }else{
                lines.push(line+'\r\n');
            }
        } 
        
    );
       
    str = lines.join('');

    var uniq = {$data:1, $out:1};
    
    var p1 = '$out.push(';
    var p2 = ');';
    
    var header = 'var ';
    var body = '$out = [];';
    var footer = 'return $out.join("")';
    
    foreach(str.split('{{'), function(code){
        
        code = code.split('}}');
        
        if(code.length == 1){
            body += html(code[0]);
        }else{
            body += makejs(code[0]);
            if(code[1]){
                body += html(code[1]);
            }
        }
    
    });
    
    var code = header + body + footer;

    try{
        return format(trim(Function("$utils", "$data", code)(utils, data)));
    }catch(e){
        throw e;
    }
    
    function html(code){
        return p1 + stringify(code) + p2 +'\n';
    }
    
    function makejs(code){

        code = parse(code);
        
        foreach(getVariable(code), function(name){
            
            if(uniq[name]){
                return;
            }

            var value;
                
            // 声明模板变量
            // 赋值优先级:
            // utils > data
            if (utils[name]) {
                value = "$utils." + name;
            }else if(data[name]){
                value = "$data." + name;
            }else{
                value = 'null';
            }
            
            header += name + "=" + value + ",";
            
            uniq[name] = true;
            
        });
        
        return code + "\n";
    }
    
    //分析逻辑指令
    function parse(code){
    
        var split = code.split(' ');
        var key = split.shift();
        var args = split.join(' ');
        
        switch(key){
            
            case 'if':
            
                code = 'if('+ args +'){';
                break;
                
            case 'else':
            
                if (split.shift() == 'if') {
                    code = '}else if('+ split.join(' ') +'){';
                } else {
                    code = '}else{';
                }
                break;

            case '/if':

                code = '}';
                break;
                
            case 'each':
                
                var object = split[0] || '$data';
                var as     = split[1] || 'as';
                var value  = split[2] || '$value';
                var index  = split[3] || '$index';
                
                var param   = value +','+ index;
                
                if (as != 'as') {
                    object = '[]';
                }
                
                code =  '$each('+ object +',function('+ param +'){';
                break;

            case '/each':

                code = '});';
                break;
            case 'module':
                
                var mpath_mdata = args.split(' ');
                var mpath = mpath_mdata.shift();
                var mdata = mpath_mdata.join(' ');
                
                if(mdata){
                    mdata = trim(mdata)
                        .replace(/\\\\/g, '\\')
                        .replace(/\\\{/g, '{')
                        .replace(/\\\}/g, '}')
                        ;
                }

                if(mdata){
                    code = '$out.push(function(){ try{ var $it = '+ mdata +';}catch(e){return "<error>";} try{var $out = [];';
                }else{
                    code = '$out.push(function($it, $out){$it = {};try{$out = [];';
                }
                
                break;
            case '/module':
                code = ' return $out.join("");}catch(e){return "<error>";} }());';
                break;
            case 'break':
                code = 'return false;';
                break;
            case 'continue':
                code = 'return;';
                break;
            default:
                
                if(/^#/.test(key)){
                    code = "$tostring("+ code.substr(1) +")";
                }else{
                    code = "$escape("+ code +")";
                }

                code = p1 + code + p2;
        }
        
        return code;
        
    }
    
    function trim(str){
        return str.replace(/^\s+|\s$/g, '');
    }
    
}

function escape(str){
    return tostring(str)
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;');
}

function tostring(str){
    if(str == null){
        return '';
    }
    return ''+ str;
}

function foreach(data, callback){
    if({}.toString.call(data) == '[object Array]'){
        for(var i = 0; i < data.length; i++){
            callback.call(data, data[i], i, data);
        }
    }else{
        for (var i in data) {
            callback.call(data, data[i], i);
        }
    }
}

function stringify(str){
    return "'"+ (''+ str)
    .replace(/('|\\)/g, '\\$1')
    .replace(/\r/g, '\\r')
    .replace(/\n/g, '\\n') + "'";
}

//获取模板中的变量名
function getVariable(code){
    
    var KEYWORDS =
        // 关键字
        'break,case,catch,continue,debugger,default,delete,do,else,false'
        + ',finally,for,function,if,in,instanceof,new,null,return,switch,this'
        + ',throw,true,try,typeof,var,void,while,with'

        // 保留字
        + ',abstract,boolean,byte,char,class,const,double,enum,export,extends'
        + ',final,float,goto,implements,import,int,interface,long,native'
        + ',package,private,protected,public,short,static,super,synchronized'
        + ',throws,transient,volatile'

        //+ ',Math'
        
        // ECMA 5 - use strict
        + ',arguments,let,yield'

        + ',undefined';

    var REMOVE_RE = /\/\*[\w\W]*?\*\/|\/\/[^\n]*\n|\/\/[^\n]*$|"(?:[^"\\]|\\[\w\W])*"|'(?:[^'\\]|\\[\w\W])*'|\s*\.\s*[$\w\.]+/g;
    var SPLIT_RE = /[^\w$]+/g;
    var KEYWORDS_RE = new RegExp(["\\b" + KEYWORDS.replace(/,/g, '\\b|\\b') + "\\b"].join('|'), 'g');
    var NUMBER_RE = /^\d[^,]*|,\d[^,]*/g;
    var BOUNDARY_RE = /^,+|,+$/g;
    var SPLIT2_RE = /^$|,+/;

    // 获取变量
    getVariable = function(code){
        return code
        .replace(REMOVE_RE, '')
        .replace(SPLIT_RE, ',')
        .replace(KEYWORDS_RE, '')
        .replace(NUMBER_RE, '')
        .replace(BOUNDARY_RE, '')
        .split(SPLIT2_RE);
    };
    
    return getVariable(code);
}

function format(code){ //格式化对齐缩进
    var 
    lineText = code.split('\n'),
    linePadding = Array(30).join(' ');
    for(var i = 1; i < lineText.length; i++){
        
        if(/^\s*$/.test(lineText[i])){ //过滤空行
            continue;
        }
        
        var curPadding = lineText[i].match(/^\s*/)[0];
        if(curPadding){
            linePadding =
                curPadding.length < linePadding.length
                ? curPadding
                : linePadding;
        }else{
            linePadding = '';
            break;
        }
        
    }
    
    return code.replace(RegExp('^'+linePadding, 'mg'), '');
}
    
})();

/*===== mstoreDev/common#localStorege:0 =====*/

var $localStorege = function(){
    
    if(!window.localStorage){
        return function(){};
    }
    
    return exports;
    
    function exports(key, value){
		if(arguments.length == 1){ //get
			var originValue = localStorage.getItem(key);
			if(/^\[\[\[(JSON|BOOL|NUMB)\]\]\]:/.test(originValue)){
				var source = originValue.match(/^\[\[\[(JSON|BOOL|NUMB)\]\]\]:(.+)/);
				var dataType = source[1];
				var dataValue = source[2];
				value = ({
					JSON: function(){
						return JSON.parse(dataValue);
					},
					BOOL: function(){
						return dataValue == 'true' ? true : false;
					},
					NUMB: function(){
						return parseFloat(dataValue);
					}
				})[dataType]();
			}else{
				value = originValue;
			}
			return value;
		}else{ //set
			if(value == null){
				localStorage.removeItem(key);
			}else{
				if(typeof value == 'number'){
					value = '[[[NUMB]]]:'+ value;
				}else if(typeof value == 'object'){
					value = '[[[JSON]]]:'+ JSON.stringify(value);
				}else if(typeof value == 'boolean'){
					value = '[[[BOOL]]]:' + value;
				}
				localStorage.setItem(key, value);
			}
		}
    }
    
}();

/*===== mstoreDev/common#action:0 =====*/

$$('action.openCreateProject', function(){
    
    $(document).on('click', '[mstoreClick=createProjectSubmit]', function(){
        var $wrapper = $(this).parents('.createProject');
        /*
        return console.info('createProject.data', {
			cmd: 'project_create',
            id: $wrapper.find('[name=id]').val(), 
            name: $wrapper.find('[name=name]').val(), 
            desc: $wrapper.find('[name=desc]').val(), 
            type: $wrapper.find('[name=type]').val()
        });*/
        $util.ajax(function(resp){
            if(resp.err){
                layer.alert(resp.err);
            }else if(resp.reload){
                location.reload();
            }
        }, {
			cmd: 'project_create',
            id: $wrapper.find('[name=id]').val(), 
            name: $wrapper.find('[name=name]').val(), 
            desc: $wrapper.find('[name=desc]').val(), 
            type: $wrapper.find('[name=type]').val()
        });
    });
    
    return function(){
        layer.open({
            id:'createProject',
            type: 1,
            maxWidth:'600px',
            offset:'20.0rem',
            title: '创建项目',
            skin: 'layui-layer-lan', //样式类名
            //anim: 1,
            //shadeClose: true, //开启遮罩关闭
            move:false,
            resize:false,
            yes: function(index, layero){
                layer.close(index);
            },
            content: $rtpl(function(){/*
                <ul class="createProject formBox">
                    <li><label>项目ID：</label><input name="id">
                    <li><label>项目名称：</label><input name="name">
                    <li><label>项目描述：</label><input name="desc">
                    <li><label>项目类型：</label>
                        <select name="type">
                            <option value="private">私有项目
                            <option value="public">公有项目
                        </select>
                    <li class="layui-layer-btn">
                        <a class="submit" mstoreClick="createProjectSubmit">确定</a>
                    </li>
                </ul>
            */})
        });
    };
    
});

/*===== mstoreDev/common#action:1 =====*/

$$('action.openCreateStore', function(){
    
    $(document).on('click', '[mstoreClick=createStoreSubmit]', function(){
        
        var $wrapper = $('#createStoreWindow');
        var hasError = false;
        var projectId = $wrapper.find('[name=projectId]').val();
        var storeId = $wrapper.find('[name=storeId]').val();
        var storeName = $wrapper.find('[name=storeName]').val();
        var storeType = $wrapper.find('[name=storeType]').val();
            
        'storeId storeName'.split(' ').forEach(function(name){
            if(/^\s*$/.test($wrapper.find('[name='+ name +']').val())){
                hasError = true;
            }
        });
            
        if(hasError){
            return layer.alert('请填写完整的字段！');
        }
            
        $util.ajax(function(resp){
            if(resp.err){
                if(resp.err == 'BREAK'){
                    layer.alert('仓库已存在，跳过创建');
                }else{
                   layer.alert(resp.err); 
                }
            }else{
                if(storeType == 'page' || storeType == 'xpage'){
                    location.href = ['/', projectId, '/', storeId, '.html?$edit=mstore'].join('');
                }else{
                    location.href = location.href.replace(/\$cache=\d+/, '') + '&$cache='+ +new Date;
                    //location.reload();
                }
            }
        }, {
            cmd:'STORE_CREATE', 
            id: storeId, 
            name: storeName,
            type: storeType,
            projectId: projectId
        });
    });
    
    return function(projectId, storeId){
        layer.open({
            id: 'createStoreWindow',
            type: 1,
            maxWidth: '600px',
            offset: '20.0rem',
            title: '创建仓库',
            skin: 'layui-layer-lan', //样式类名
            //anim: 1,
            //shadeClose: true, //开启遮罩关闭
            move: false,
            resize: false,
            yes: function(index, layero){
                layer.close(index);
            },
            content: $rtpl(function(){/*
                <input type="hidden" name="projectId" value="{{projectId}}">
                <ul class="createStoreWindow formBox">
                    {{if storeId}}
                        <input type="hidden" name="storeId" value="{{storeId}}">
                    {{else}}
                    <li><label>仓库ID：</label><input name="storeId">
                    {{/if}}
                    <li><label>仓库名称：</label><input name="storeName">
                    {{if storeId}}
                        <input type="hidden" name="storeType" value="mods">
                    {{else}}
                    <li><label>仓库类型：</label>
                        <select name="storeType">
                            <option value="page">项目页面
                            <option value="mods">项目模块
                            <option value="xpage">辅助页面
                        </select>
                    {{/if}}    
                    <li class="layui-layer-btn">
                        <a class="submit" mstoreClick="createStoreSubmit">确定</a>
                </ul>
            */}, {
                projectId: projectId,
                storeId: storeId
            })
        });
    };
    
});    

/*===== mstoreDev/common#action:2 =====*/

$$('action.openCreateModule', function(){
    
    $(document).on('click', '[mstoreClick=createModuleSubmit]', function(){
        
        var $wrapper = $('#createModuleWindow');
        var projectId = $wrapper.find('[name=projectId]').val();
        var storeId = $wrapper.find('[name=storeId]').val();
        var moduleId = $wrapper.find('input[name=moduleId]').val();
        var moduleName = $wrapper.find('input[name=moduleName]').val();
        var path = projectId +'/'+ storeId;
        
        if(/>/.test(moduleName)){
            return layer.alert('模块名不合法');
        }
        if(/^\s*$/.test(moduleName)){
            return layer.alert('模块名不能为空');
        }
        
        $util.ajax(function(resp){
            if(resp.err){
                layer.alert(err);
            }else{
                $$.page.reload();
                $$.editor.open(path + '#' + moduleId);
            }
        },{
            cmd: 'MODULE_CREATE',
            projectId: projectId,
            storeId: storeId,
            moduleId: moduleId,
            moduleName: moduleName
        });
        
    });
    
    return function(projectId, storeId, moduleId){
        layer.open({
            id:'createModuleWindow',
            type: 1,
            maxWidth:'600px',
            offset: '20.0rem',
            title: '创建模块',
            skin: 'layui-layer-lan', //样式类名
            //anim: 1,
            //shadeClose: true, //开启遮罩关闭
            move: false,
            resize: false,
            yes: function(index, layero){
                layer.close(index);
            },
            content: $rtpl(function(){/*
                <ul class="createModule formBox">
                    <li><label>模块名称：</label>
                        <input name="projectId" value="{{projectId}}" type=hidden>
                        <input name="storeId" value="{{storeId}}" type=hidden>
                        <input name="moduleId" value="{{moduleId}}" type=hidden>
                        <input name="moduleName">
                    <li class="layui-layer-btn">
                        <a class="submit" mstoreClick="createModuleSubmit">确定</a>
                </ul>
            */}, {
                projectId: projectId,
                storeId: storeId,
                moduleId: moduleId
            })
        });
    };
    
});    

/*===== mstoreDev/common#action:3 =====*/

$$('action.openDir', function(){
    return function(dirPath){
        dirPath = dirPath || '';
        //alert('打开目录'+ dirPath);
        //return console.info('action.openDir', dirPath);
        $util.ajax(function(resp){
            if(resp.mstoreProxy){
                $.ajax({
                    async:false,
                    url: 'http://127.0.0.1:1986/',
                    type: "GET",
                    dataType: 'jsonp',
                    data: {
                        cmd: 'openProjectFolder',
                        path: resp.mstoreProxy.path
                    }
                });
            }
        }, {
            cmd: 'dir_open',
            path: dirPath
        });
    };
});    

/*===== mstoreDev/common#action:4 =====*/

$$('action.addStoreTask', function(){
    return function(path, callback){
        $util.ajax(function(resp){
            if(resp.err){
                layer.alert(resp.err);
            }else{
                callback();
            }
        }, {
            cmd: 'task_add',
            path: path
       });
    };
});    

/*===== mstoreDev/common#select:0 =====*/

$$('select', function(){
    
    var pid = 0;
    var onchanges = {};
    
    $(document).on('click', '.fmSelect .text, .fmSelect .bt_arrow', function(e){ //显示隐藏下拉
        var $container = $(this).parents('.fmSelect');
        if(!$container.hasClass('actived')){
            e.stopPropagation();
            $('.fmSelect').removeClass('actived');
            $container.addClass('actived');
        }
    });
    
    $(document).on('click', function(e){
        $('.fmSelect').removeClass('actived');
    });
    
    $(document).on('click', '.fmSelect .options li', function(){
        
        var $container = $(this).parents('.fmSelect');
        var oldValue = $container.find('.realInput').val();
        var newValue = $(this).attr('data-value');
        var newText = $(this).attr('data-text');
        
        if(oldValue == newValue){
            return;
        }
        
        var isPreventDefault = false;
        var $button = $(this);
        var myPid = $container.attr('data-pid');
        
        if(onchanges[myPid]){
            onchanges[myPid]({
                $container: $container,
                oldValue: oldValue,
                newValue: newValue,
                preventDefault: function(){
                    isPreventDefault = true;
                },
                restore: function(){
                    dafaultEvent();
                }
            });
        }
        
        if(!isPreventDefault){
            dafaultEvent();
        }
        
        function dafaultEvent(){
            $container.find('.text').html($button.attr('data-text'));
            $container.find('.realInput').val(newValue);
            $container.find('.options li').removeClass('checked');
            $button.addClass('checked');
        }
        
    });
    
    $(document).on('setValue', '.fmSelect', function(e, value){
        setValue($(this), value); 
    });
    
    $(document).on('render', '.fmSelect', function(e, options, value){
       render($(this), buildOptions(options), value);
    });
    
    return exports;
    
    function exports(selector, option){
        
        var $container = $(selector);
        if(!$container.attr('data-pid')){
           initSelect($container, option);
        }
        
    }
    
    function initSelect($container, option){
        
        var myPid = ++pid;
        $container.attr('data-pid', myPid);
        
        if(option.onchange){
            onchanges[myPid] = option.onchange;
        }
        
        if(option.width){
           $container.width(option.width);
        }

        var optionItems = buildOptions(option.options);
        var value = $container.find('.realInput').val();
        var text; //显示的文本
        if(value){
            $.each(optionItems, function(i, item){
                if(item.value == value){
                    text = item.text;
                    return false;
                }
            });
        }else{
            value = optionItems[0].value;
            text = optionItems[0].text;
        }

        $container.find('.text').html(text);
        render($container, optionItems, value);

    }
    
    function buildOptions(options){
        var optionItems = [];
        $.each(typeof options == 'string' ? options.split(',') : options, function(i, item){
            if(typeof item == 'string'){
                item = item.split(':');
                optionItems.push({value:item[0], text:item[1]||item[0]});
            }else{
                for(var text in item){
                    optionItems.push({value:text, text:item[text]});
                }
            }
        });
        return optionItems;
    }
    
    function setValue($container, value){
        $container.find('.options li').each(function(){
            if($(this).attr('data-value') == value){
                $(this).click();
                return false;
            }
        }); 
    }
    
    function render($container, optionItems, value){
        
        $container.find('.options').html($rtpl(function(){/*
            {{each options as option}}
            <li data-value="{{option.value}}" data-text="{{option.text}}" {{if value == option.value}}class="checked"{{/if}}>{{option.text}}</li>
            {{/each}}
        */}, {options:optionItems, value:value}));
        
        setValue($container, value);
        
    }
    
});   
